package com.yb.flowable.controller;

import com.yb.flowable.common.Result;
import com.yb.flowable.param.FlowableUser;
import com.yb.flowable.service.FlowableUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Description:flowable的用户接口类---->一般业务结合工作流使用的时候,
 * 为了方便不去做用户同步或者其他的东西,就是不在flowable存储过多的东西,
 * 只是存储流程必要的用户信息(一般就是用户名),其他的权限等认证就使用原有系统的那一套东西
 * @author biaoyang
 * date 2019/3/15 00159:53
 */
@Api(tags = "用户流程控制")
@Validated
@RestController
@AllArgsConstructor
public class FlowableUserController {
    private FlowableUserService flowableUserService;

    @ApiOperation("添加flowable用户")
    @PostMapping("/addUser")
    public Result<Object> addUser(@Valid @RequestBody FlowableUser flowableUser) {
        String result = flowableUserService.addUser(flowableUser);
        return Result.success(result);
    }

    @ApiOperation("flowable用户登录")
    @PostMapping("/login")
    public Result<Object> login(HttpSession session, @Valid @RequestBody FlowableUser flowableUser) {
        String result = flowableUserService.login(session, flowableUser);
        return Result.success(result);
    }

    @ApiOperation("退出登录操作")
    @GetMapping("/logout")
    public Result<Object> login(HttpSession session) {
        session.removeAttribute("username");
        return Result.success("操作成功");
    }

    @ApiOperation("查询所有flowable用户")
    @GetMapping("/queryAllUser")
    public Result<Object> queryAllUser() {
        List<User> result = flowableUserService.queryAllUser();
        return Result.success(result);
    }

    @ApiOperation("查询所有flowable组")
    @GetMapping("/queryAllGroup")
    public Result<Object> queryAllGroup() {
        List<Group> result = flowableUserService.queryAllGroup();
        return Result.success(result);
    }

    @ApiOperation("通过用户组查询flowable用户")
    @GetMapping("/queryUserByGroup")
    public Result<Object> queryUserByGroup(
             @ApiParam("组名称")
            @NotBlank(message = "组名不能为空")
            @Length(max = 20, message = "组名不能超过20字")
            @RequestParam String groupName) {
        List<User> result = flowableUserService.queryUserByGroup(groupName);
        return Result.success(result);
    }

    /**
     * 四种常见的java排序算法实践(选择排序法/插入排序法/冒泡排序法/快速排序法)
     */
    public static void mySort() {
        Integer[] array = {2, -5, 3, 1, 10, 12};
        int temp;
        //利用数组工具正序排序(只能处理正序,倒序可以反着遍历或者转换为数组,然后反转)
        System.out.println(Arrays.asList(array));
        Arrays.sort(array);
        System.out.println(Arrays.asList(array));
        System.err.println("--------------------------------------------------------");
        //将数组转换为集合
        List<Integer> list = Arrays.asList(array);
        List<Integer> h = list.stream().sorted().collect(Collectors.toList());
        List<Integer> k = list.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
        System.err.println(h);
        System.err.println(k);
        System.err.println("--------------------------------------------------------");
        Comparator<Object> objectComparator = Collections.reverseOrder();
        Comparator<Integer> integerComparator = Collections.reverseOrder(Comparator.comparingInt(Integer::intValue));
        Collections.sort(list);
        System.err.println(list);
        System.out.println("--------------------------------------------------------");
        Collections.sort(list, objectComparator);
        System.err.println(list);
        System.out.println("--------------------------------------------------------");
        Collections.sort(list, integerComparator);
        System.err.println(list);
        System.out.println("--------------------------------------------------------");
        //插入排序法--性能低,比较简单(类似于摸扑克牌排序,第一个数和后面的数依次比较,第二个也是依次和后面的数比较,这样从前面一个一个的排序
        //插入是从前面依次排序,冒泡是从后面依次排序)[2, -5, 3, 1, 10, 12]
        for (int i = 1; i < array.length; i++) {
            int j;
            //这一步是必要的(实测),如果不先取出来放着,直接通过数组下标获取的值是可能是被覆盖过的值了
            temp = array[i];
            //让当前数和之前的数逐个比较换位,注意一点的是这里的循环条件(不能在for循环里写if判断比较数的大小(实测),
            //原因就是因为temp存储的值是需要覆盖在对应的调换位置上,也就是每次调换(每次循环)都要去覆盖,否则你内嵌的
            //循环在遍历的时候,可能一直在覆盖数据,导致你的数据丢失,也就是每次内嵌循环调换一次,就需要把调换的比较的那个值,
            //也就是下标是j,值是temp存储的那个值,这就是为什么看到网上使用while循环可以,我一直用for不成功的原因,因为之里使用
            //for循环反而有些不太合适,容易采坑)
            for (j = i; j > 0 && array[j - 1] > temp; j--) {
                //这个其实就是从第二个数开始,使用当前位置的数(用去比较的数,外层循环所取的值),去和前面的数依次比较
                //保证你用来比较的数总是在正确的顺序上,也就是从第二个数开始,在合适的位置插入数(后面的数),
                array[j] = array[j - 1];
            }
            array[j] = temp;
        }
        System.err.println(Arrays.asList(array));
        System.err.println("--------------------------------------------------------");
        //冒泡排序法--性能低,比较简单(相邻的数比较,也就是第一次把最大的数依次往后移动到最后,第二次就是次大的,依次类推,
        // 插入是从前面依次排序,冒泡是从后面依次排序)
        for (int i = 0; i < array.length - 1; i++) {
            //这里的i的循环只是提供循环的次数(第一次执行完后排序了最大的数,所以就会少一次循环,因为每次j都是从0开始的)
            for (int j = 0; j < array.length - 1; j++) {
                if (array[j] > array[j + 1]) {
                    temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
            }
        }
        System.err.println(Arrays.asList(array));
        System.err.println("--------------------------------------------------------");
        //选择排序法--性能低,比较简单(在要排序的一组数中,选出最小的一个数与第一个位置的数交换,然后在剩下的数当中再找最小的与第二个位置的数交换,
        //如此循环到倒数第二个数和最后一个数比较为止)
        for (int i = 0; i < array.length; i++) {
            //比较的都是i下标后的数,所以j是i的后一位
            for (int j = i+1; j < array.length; j++) {
                //如果i下标的数大于j下标的数
                if (array[i]>array[j]){
                    temp=array[j];
                    array[j]=array[i];
                    array[i]=temp;
                }
            }
        }
        System.out.println(Arrays.asList(array));
        System.err.println("--------------------------------------------------------");
        //快速排序法--性能高,比较复杂(速度的快慢取决于基准的选择是否合适,选用一个基准(数),然后左右查找,左边只留比基准书小的数,
        //而右边只留比基准数大的,否则调换位置,然后递归调调用,重复处理,基准数左边部分和右边部分)
        //时间复杂度
        //最好情况：O(nlogn)
        //最坏情况：O(n2)
        //平均情况：O(nlogn)
        //空间复杂度： O(logn) （栈占用的空间）
        //稳定性： 不稳定
        int left = 0;
        int right = array.length - 1;
        //调用方法
        quickSort(array, left, right);
        System.out.println(Arrays.asList(array));
    }

    /**
     * 进行快速排序的方法
     *
     * @param array
     * @param left
     * @param right
     */
    public static void quickSort(Integer[] array, int left, int right) {
        //定义变量
        int i, j, temp, base;
        if (left > right) {
            //左下标需要小于等于右下标
            return;
        }
        //获取基准数(这里我用第一个元素作为基准数)
        base = array[left];
        i = left;
        j = right;
        //判断并处理逻辑
        while (i < j) {
            //从右往左查找,如果大于基准数就不管,否则跳出循环
            while (i < j && array[j] >= base) {
                j--;
            }
            //-------------------------------------------------------------------------------
            //这里需要注意,必须先执行从右边查找(实测如果不这样得到的结果将不对)
            //-------------------------------------------------------------------------------
            //从左往右查找,如果小于基准数就不管,否则跳出循环
            while (i < j && array[i] <= base) {
                i++;
            }
            //如果满足条件则交换(这里的判断需要的)
            if (i < j) {
                //用左边的大于基准数的数和右边小于基准数的数交换位置
                temp = array[j];
                array[j] = array[i];
                array[i] = temp;
            }
        }
        //最后将基准为与i和j相等位置的数字交换(此时j=i,如果不相等,则会一直在while循环里,故而此时用i和j都是一样的)
        array[left] = array[i];
        array[i] = base;
        //递归调用左半数组
        quickSort(array, left, j - 1);
        //递归调用右半数组
        quickSort(array, j + 1, right);
    }

}
